<template>
    <view class="kline-wrapper" :style="{ width: '100%', height: '100%' }">
        <!-- K线图表容器 -->
        <view class="kline-container"
              @touchstart="handleTouchStart"
              @touchend="handleTouchEnd">
            <!-- SVG K线图 - 完全铺满容器 -->
            <svg v-if="displayData && displayData.length > 0"
                :viewBox="`0 0 ${svgWidth} ${svgHeight}`"
                class="svg-canvas"
                preserveAspectRatio="none">
                
                <!-- 背景 -->
                <rect width="100%" height="100%" fill="#ffffff"/>
                
                <!-- Y轴价格刻度线和文字 -->
                <g v-for="i in 5" :key="`price-${i}`">
                    <!-- 价格刻度线（虚线） -->
                    <line 
                        x1="0" :y1="(svgHeight / 5) * i"
                        :x2="svgWidth" :y2="(svgHeight / 5) * i"
                        stroke="#e0e0e0" stroke-width="0.5" stroke-dasharray="2,2"/>
                    <!-- 价格文字（右侧） -->
                    <text 
                        :x="svgWidth - 3"
                        :y="(svgHeight / 5) * i + 3"
                        text-anchor="end"
                        font-size="10"
                        fill="#999">
                        {{ getPriceAtY((svgHeight / 5) * i).toFixed(2) }}
                    </text>
                </g>
                
                <!-- X轴时间刻度线和文字 -->
                <g v-for="i in 5" :key="`time-${i}`">
                    <!-- 时间刻度线（虚线） -->
                    <line 
                        :x1="(svgWidth / 5) * i" :y1="0"
                        :x2="(svgWidth / 5) * i" :y2="svgHeight"
                        stroke="#e0e0e0" stroke-width="0.5" stroke-dasharray="2,2"/>
                    <!-- 时间文字（底部） -->
                    <text 
                        :x="(svgWidth / 5) * i"
                        :y="svgHeight - 2"
                        text-anchor="middle"
                        font-size="10"
                        fill="#999">
                        {{ getTimeAtIndex(Math.floor(displayData.slice(hiddenFromStart).length * i / 5)).substring(11) }}
                    </text>
                </g>
                
                <!-- K线数据 -->
                <g v-for="(bar, index) in displayData.slice(hiddenFromStart)" :key="`bar-${index}`" @click="selectBar(bar)">
                    <!-- 蜡烛图 -->
                    <template v-if="chartType === 'candle'">
                        <!-- 上影线长度 = 总长度的25% -->
                        <line 
                            :x1="getBarX(index, true)"
                            :y1="getHighY(bar)"
                            :x2="getBarX(index, true)"
                            :y2="getHighY(bar) + (getLowY(bar) - getHighY(bar)) * 0.25"
                            :stroke="bar.close >= bar.open ? '#00aa00' : '#ff4444'"
                            stroke-width="1"
                            style="cursor: pointer;"/>
                        <!-- 实体 -->
                        <rect 
                            :x="getBarX(index)"
                            :y="Math.min(getOpenY(bar), getCloseY(bar))"
                            :width="barWidth"
                            :height="Math.max(Math.abs(getCloseY(bar) - getOpenY(bar)), 2)"
                            :fill="bar.close >= bar.open ? '#00aa00' : '#ff4444'"
                            style="cursor: pointer;"/>
                        <!-- 下影线长度 = 总长度的25% -->
                        <line 
                            :x1="getBarX(index, true)"
                            :y1="getLowY(bar)"
                            :x2="getBarX(index, true)"
                            :y2="getLowY(bar) - (getLowY(bar) - getHighY(bar)) * 0.25"
                            :stroke="bar.close >= bar.open ? '#00aa00' : '#ff4444'"
                            stroke-width="1"
                            style="cursor: pointer;"/>
                    </template>
                    
                    <!-- 面积图 -->
                    <template v-else-if="chartType === 'area'">
                        <circle 
                            :cx="getBarX(index, true)"
                            :cy="getValueY(bar)"
                            r="3"
                            fill="#4a90e2"
                            style="cursor: pointer;"/>
                    </template>
                </g>
                
                <!-- 面积图填充路径 -->
                <path v-if="chartType === 'area' && displayData && displayData.length > 0"
                    :d="getAreaPath()"
                    fill="rgba(74, 144, 226, 0.2)"
                    stroke="none"/>
                
                <!-- 面积图折线 -->
                <polyline v-if="chartType === 'area' && displayData && displayData.length > 0"
                    :points="getAreaPoints()"
                    fill="none"
                    stroke="#4a90e2"
                    stroke-width="1"/>
                
                <!-- Y轴最高价格刻度（右上角） -->
                <text v-if="maxPrice > 0"
                    :x="svgWidth - 5"
                    :y="15"
                    text-anchor="end"
                    font-size="12"
                    fill="#666">
                    {{ maxPrice.toFixed(2) }}
                </text>
                
                <!-- X轴时间刻度（右下角） -->
                <text v-if="lastTime"
                    :x="svgWidth - 5"
                    :y="svgHeight - 5"
                    text-anchor="end"
                    font-size="12"
                    fill="#666">
                    {{ lastTime }}
                </text>
            </svg>
            <view v-else class="empty-placeholder">
                <text>📭 等待数据加载...</text>
            </view>
            
            <!-- 选中柱状图信息显示 -->
            <view v-if="selectedBarInfo" class="bar-info-panel">
                <view class="info-row">
                    <text class="info-label">时间:</text>
                    <text class="info-value">{{ formatTime(selectedBarInfo.time) }}</text>
                </view>
                <view v-if="chartType === 'candle'" class="info-row">
                    <text class="info-label">开: {{ selectedBarInfo.open.toFixed(2) }}</text>
                    <text class="info-separator">|</text>
                    <text class="info-label">高: {{ selectedBarInfo.high.toFixed(2) }}</text>
                </view>
                <view v-if="chartType === 'candle'" class="info-row">
                    <text class="info-label">低: {{ selectedBarInfo.low.toFixed(2) }}</text>
                    <text class="info-separator">|</text>
                    <text class="info-label">收: {{ selectedBarInfo.close.toFixed(2) }}</text>
                </view>
                <view v-if="chartType === 'area'" class="info-row">
                    <text class="info-label">价格: {{ selectedBarInfo.value.toFixed(2) }}</text>
                </view>
                <view class="info-close" @click="selectedBarInfo = null">✕</view>
            </view>
        </view>
    </view>
</template>

<script setup>
import { ref, watch, onMounted, computed } from 'vue';

const props = defineProps({
    data: {
        type: Array,
        default: () => []
    },
    chartType: {
        type: String,
        default: 'candle'
    },
    chartHeight: {
        type: Number,
        default: 300
    }
});

const marginLeft = 20; // 左边距（SVG坐标单位）
const marginRight = 20; // 右边距（SVG坐标单位）
const svgWidth = ref(750);
const svgHeight = ref(600);
const baseBarSpacing = 10; // 基础条形间距（2rpx）
const touchStartX = ref(0);
const scrollOffset = ref(0); // X轴滚动偏移量（像素）
let dynamicBarSpacing = baseBarSpacing; // 动态间隙值
const displayCount = ref(null); // 当前显示的数据条数（默认显示全部）
const hiddenFromStart = ref(50); // 从开始位置隐藏的数据条数（默认隐藏75条，只显示最新25条，实现放大效果）
const selectedBarInfo = ref(null); // 选中柱状图的信息 {time, open, high, low, close, value}

// 显示的数据（根据从开始隐藏的数据条数处理）
const displayData = computed(() => {
    if (!props.data || props.data.length === 0) return [];
    
    // 根据不同图表类型使用不同数据格式
    if (props.chartType === 'area') {
        // 面积图：只需要value
        return props.data.map(item => ({
            time: item.time,
            value: item.value !== undefined ? item.value : item.close
        }));
    } else {
        // 蜡烛图：需要open, high, low, close
        return props.data.map(item => ({
            time: item.time,
            open: item.open || item.close || item.value || 0,
            high: item.high || item.close || item.value || 0,
            low: item.low || item.close || item.value || 0,
            close: item.close || item.value || 0
        }));
    }
});

// 基础条形宽度（所有数据均分容器宽度）
const baseBarWidth = computed(() => {
    const availableWidth = svgWidth.value - marginLeft - marginRight;
    return Math.max(1, Math.floor(availableWidth / displayData.value.length));
});

// 计算可见的K线数量
const visibleBarsCount = computed(() => {
    const totalBars = displayData.value.length;
    
    // 计算显示的数据条数 = 总条数 - 隐藏的条数
    const visibleCount = totalBars - hiddenFromStart.value;
    
    // 最少显示5条
    return Math.max(5, visibleCount);
});

// 条形宽度（根据可见数据数量动态放大）
const barWidth = computed(() => {
    const availableWidth = svgWidth.value - marginLeft - marginRight;
    // 根据可见数据条数来计算条形宽度，实现自动放大
    return Math.max(1, Math.floor(availableWidth / visibleBarsCount.value));
});

// 当前有效间隙（根据放大倍数动态计算）
const barSpacing = computed(() => {
    // 计算放大倍数 = barWidth / baseBarWidth
    const zoomRatio = barWidth.value / baseBarWidth.value;
    // 实际间隙 = 动态间隙 × 放大倍数
    return Math.max(2, Math.floor(dynamicBarSpacing * zoomRatio));
});

// 计算价格范围
const priceRange = computed(() => {
    if (!displayData.value || displayData.value.length === 0) return 1;
    
    // 只计算显示范围内的数据
    const visibleData = displayData.value.slice(hiddenFromStart.value);
    if (visibleData.length === 0) return 1;
    
    let minPrice = Infinity;
    let maxPrice = -Infinity;
    
    visibleData.forEach(bar => {
        if (props.chartType === 'area') {
            minPrice = Math.min(minPrice, bar.value || 0);
            maxPrice = Math.max(maxPrice, bar.value || 0);
        } else {
            minPrice = Math.min(minPrice, bar.low || 0);
            maxPrice = Math.max(maxPrice, bar.high || 0);
        }
    });
    
    return maxPrice - minPrice || 1;
});

const minPrice = computed(() => {
    if (!displayData.value || displayData.value.length === 0) return 0;
    
    // 只计算显示范围内的数据
    const visibleData = displayData.value.slice(hiddenFromStart.value);
    if (visibleData.length === 0) return 0;
    
    let min = Infinity;
    visibleData.forEach(bar => {
        if (props.chartType === 'area') {
            min = Math.min(min, bar.value || 0);
        } else {
            min = Math.min(min, bar.low || 0);
        }
    });
    
    return min === Infinity ? 0 : min;
});

// 计算最高价格（只计算显示的数据）
const maxPrice = computed(() => {
    if (!displayData.value || displayData.value.length === 0) return 0;
    
    // 只计算显示范围内的数据
    const visibleData = displayData.value.slice(hiddenFromStart.value);
    if (visibleData.length === 0) return 0;
    
    let max = -Infinity;
    visibleData.forEach(bar => {
        if (props.chartType === 'area') {
            max = Math.max(max, bar.value || 0);
        } else {
            max = Math.max(max, bar.high || 0);
        }
    });
    
    return max === -Infinity ? 0 : max;
});

// 获取最后一条显示数据的时间
const lastTime = computed(() => {
    if (!displayData.value || displayData.value.length === 0) return '';
    
    // 获取显示范围内的最后一条数据
    const visibleData = displayData.value.slice(hiddenFromStart.value);
    if (visibleData.length === 0) return '';
    
    const lastBar = visibleData[visibleData.length - 1];
    const time = lastBar.time;
    if (typeof time === 'number' && time > 0) {
        const timestamp = time > 10000000000 ? time : time * 1000; // 如果是秒级则乘以1000
        const date = new Date(timestamp);
        return date.toLocaleString('zh-CN', { month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' });
    }
    return time?.toString() || '';
});

// 计算K线的X坐标
const getBarX = (index, isMidpoint = false) => {
    // index 是在 displayData.slice(hiddenFromStart) 中的索引
    // 显示的数据条数
    const visibleCount = visibleBarsCount.value;
    
    // X坐标从右边开始计算，右对齐
    // 最右边的数据应该靠近svgWidth - marginRight
    const totalWidth = (baseBarWidth.value + dynamicBarSpacing) * visibleCount;
    const rightEdge = svgWidth.value - marginRight;
    const startX = rightEdge - totalWidth;
    
    // 当前数据的X坐标：基础位置 + 索引位置 + 滑动偏移
    const x = startX + (baseBarWidth.value + dynamicBarSpacing) * index + scrollOffset.value;
    
    // 判断是否超出需求的范围
    if (x + baseBarWidth.value < marginLeft || x > svgWidth.value - marginRight) {
        return -10000; // 完全超出范围，不绘制
    }
    
    return isMidpoint ? x + baseBarWidth.value / 2 : x;
};

// 计算High的Y坐标
const getHighY = (bar) => {
    const high = bar.high || 0;
    return svgHeight.value - ((high - minPrice.value) / priceRange.value) * svgHeight.value;
};

// 计算Low的Y坐标
const getLowY = (bar) => {
    const low = bar.low || 0;
    return svgHeight.value - ((low - minPrice.value) / priceRange.value) * svgHeight.value;
};

// 计算Open的Y坐标
const getOpenY = (bar) => {
    const open = bar.open || 0;
    return svgHeight.value - ((open - minPrice.value) / priceRange.value) * svgHeight.value;
};

// 计算Close的Y坐标
const getCloseY = (bar) => {
    const close = bar.close || 0;
    return svgHeight.value - ((close - minPrice.value) / priceRange.value) * svgHeight.value;
};

// 计算Value的Y坐标（面积图）
const getValueY = (bar) => {
    const value = bar.value || 0;
    return svgHeight.value - ((value - minPrice.value) / priceRange.value) * svgHeight.value;
};

// 生成面积图的接点
const getAreaPoints = () => {
    if (!displayData.value || displayData.value.length === 0) return '';
    
    // 只遍历显示范围的数据
    const visibleData = displayData.value.slice(hiddenFromStart.value);
    return visibleData.map((bar, index) => {
        const x = getBarX(index, true);
        if (x < -5000) return null; // 跳过超出范围的数据
        const y = getValueY(bar);
        return `${x},${y}`;
    }).filter(point => point !== null).join(' ');
};

// 生成面积图的填充路径
const getAreaPath = () => {
    if (!displayData.value || displayData.value.length === 0) return '';
    
    // 只使用显示范围的数据点
    const visibleData = displayData.value.slice(hiddenFromStart.value);
    const validPoints = visibleData
        .map((bar, index) => {
            const x = getBarX(index, true);
            if (x < -5000) return null; // 跳过超出范围的
            const y = getValueY(bar);
            return { x, y };
        })
        .filter(point => point !== null);
    
    if (validPoints.length === 0) return '';
    
    const topPath = validPoints.map(p => `${p.x},${p.y}`).join(' L ');
    const lastX = validPoints[validPoints.length - 1].x;
    const firstX = validPoints[0].x;
    
    return `M ${topPath} L ${lastX},${svgHeight.value} L ${firstX},${svgHeight.value} Z`;
};

// 获取Y坐标对应的价格
const getPriceAtY = (y) => {
    // 从Y坐标反推价格
    // Y从0到svgHeight，对应从maxPrice到minPrice
    const ratio = y / svgHeight.value;
    return maxPrice.value - (maxPrice.value - minPrice.value) * ratio;
};

// 获取指定索引的时间
const getTimeAtIndex = (index) => {
    const visibleData = displayData.value.slice(hiddenFromStart.value);
    if (index < 0 || index >= visibleData.length) return '';
    const item = visibleData[Math.floor(index)];
    if (!item || !item.time) return '';
    const time = item.time;
    if (typeof time === 'number' && time > 0) {
        const timestamp = time > 10000000000 ? time : time * 1000;
        const date = new Date(timestamp);
        return date.toLocaleString('zh-CN');
    }
    return time.toString();
};

// 选中柱状图
const selectBar = (bar) => {
    selectedBarInfo.value = {
        time: bar.time,
        open: bar.open || bar.value || 0,
        high: bar.high || bar.value || 0,
        low: bar.low || bar.value || 0,
        close: bar.close || bar.value || 0,
        value: bar.value || 0
    };
};

// 格式化时间
const formatTime = (time) => {
    if (typeof time === 'number' && time > 0) {
        const timestamp = time > 10000000000 ? time : time * 1000;
        const date = new Date(timestamp);
        return date.toLocaleString('zh-CN', { 
            month: '2-digit', 
            day: '2-digit', 
            hour: '2-digit', 
            minute: '2-digit',
            second: '2-digit'
        });
    }
    return time?.toString() || '';
};

// 滑动处理
const handleTouchStart = (e) => {
    touchStartX.value = e.touches[0].clientX;
};

const handleTouchEnd = (e) => {
    const touchEndX = e.changedTouches[0].clientX;
    const diff = touchEndX - touchStartX.value;
    
    if (Math.abs(diff) > 50) { // 滑动阈值
        const moveDistance = diff > 0 ? 50 : -50; // 每次滑动50单位
        
        if (moveDistance > 0) {
            // 向右滑动：显示左边的历史数据，数据向右移动（正方向）
            // 但当显示全部数据时停止
            if (hiddenFromStart.value <= 0) {
                console.log('⛔ 已到达右滑限制，正在显示全部最新数据');
                return;
            }
            hiddenFromStart.value = Math.max(0, hiddenFromStart.value - 1); // 每次减少1条隐藏
            scrollOffset.value += moveDistance; // 向右移动
        } else {
            // 向左滑动：隐藏左边的历史数据，放大显示右边最新数据，数据向左移动（负方向）
            const maxHidden = displayData.value.length - 5; // 最多隐藏到剩余5条
            if (hiddenFromStart.value >= maxHidden) {
                console.log('⛔ 已到达左滑限制，只剩5条数据');
                return;
            }
            hiddenFromStart.value = Math.min(maxHidden, hiddenFromStart.value + 1); // 每次增加1条隐藏
            scrollOffset.value += moveDistance; // 向左移动（负数）
        }
        
        const visibleCount = displayData.value.length - hiddenFromStart.value;
        console.log('🔠 滑动情况:', moveDistance > 0 ? '向右看历史' : '向左放大最新', 
                    '隐藏:', hiddenFromStart.value, '显示:', visibleCount, '条, 偏移:', scrollOffset.value);
    }
};

onMounted(() => {
    console.log('✅ K线组件挂载成功，数据:', props.data?.length || 0);
});

watch(() => props.data, (newVal) => {
    console.log('📊 K线数据更新:', newVal?.length || 0);
}, { deep: true });

watch(() => props.chartType, (newVal) => {
    console.log('🔄 图表类型变更:', newVal, '(数据已自动转换)');
});

defineExpose({
    getData: () => props.data,
    getChartType: () => props.chartType,
    resetScroll: () => { scrollOffset.value = 0; }
});
</script>

<style scoped lang="scss">
.kline-wrapper {
    width: 100%;
    height: 100%;
    background: #ffffff;
    overflow: hidden;
    display: flex;
    position: relative;
    
    .kline-container {
        width: 100%;
        height: 100%;
        background: #ffffff;
        position: relative;
        touch-action: pan-y;
        
        .svg-canvas {
            width: 100%;
            height: 100%;
        }
        
        .empty-placeholder {
            width: 100%;
            height: 100%;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 14px;
            color: #999;
        }
    }
    
    .bar-info-panel {
        position: absolute;
        top: 10px;
        left: 10px;
        background: rgba(0, 0, 0, 0.8);
        color: #fff;
        padding: 10px 15px;
        border-radius: 8px;
        font-size: 12px;
        z-index: 100;
        
        .info-row {
            display: flex;
            gap: 8px;
            margin-bottom: 6px;
            
            &:last-child {
                margin-bottom: 0;
            }
        }
        
        .info-label {
            color: #ccc;
        }
        
        .info-value {
            color: #fff;
            font-weight: bold;
        }
        
        .info-separator {
            color: #666;
        }
        
        .info-close {
            position: absolute;
            top: 5px;
            right: 8px;
            cursor: pointer;
            color: #999;
            font-size: 14px;
            
            &:active {
                color: #ccc;
            }
        }
    }
}
</style>
